# 导入算法
from hash.ConsistentHash import ConsistentHash
from hash.Hash import Hash
from hash.CommonHash import CommonHash

# 导入结点
from node.switch.LeafSwitch import LeafSwitch
from node.switch.SpineSwitch import SpineSwitch
from node.server.Server import Server

# 导入用户
from user.User import User
from user.Admin import Admin

# 数据持久化处理
import os
import pandas as pd

# 预定义参数
user_number = 10
data_length = 1000
request_number = user_number * data_length
spine_switch_number = 1
leaf_switch_number = 4
server_number = 36
same_data_ratio = 0.3
replica_number_in_spine_switch = 100
replica_number_in_leaf_switch = 10
for i in range(1, 40):
    replica_number_in_leaf_switch+=5
    # 初始化，创建算法，用户，交换机和服务器
    consistent_hash_in_spine_switch = ConsistentHash(replica_number=replica_number_in_spine_switch)
    consistent_hash_in_leaf_switch = ConsistentHash(replica_number=replica_number_in_leaf_switch)
    common_hash_in_spine_switch = CommonHash(length=server_number*replica_number_in_spine_switch)
    common_hash_in_leaf_switch = CommonHash(length=server_number*replica_number_in_leaf_switch)
    # consistent_hash_in_spine_switch = common_hash_in_spine_switch
    # consistent_hash_in_leaf_switch = common_hash_in_leaf_switch

    spine_switches = []
    for i in range(spine_switch_number):
        spine_switches.append(SpineSwitch('spine:%s' % str(i), cache_number=10000))
    leaf_switches = []
    for i in range(leaf_switch_number):
        leaf_switches.append(LeafSwitch('leaf:%s' % str(i), cache_number=10000))
    servers = []
    for i in range(server_number):
        servers.append(Server('server:%s' % str(i), cache_number=10000))
    users = []
    for i in range(user_number):
        users.append(User('user:%s' % str(i)))
    admin = Admin('admin')

    # 为交换机部署具体的算法
    for server in servers:
        consistent_hash_in_leaf_switch.add_node(server, -1)
    for leaf_switch in leaf_switches:
        leaf_switch.set_hash_algorithm(consistent_hash_in_leaf_switch)
        consistent_hash_in_spine_switch.add_node(leaf_switch, -1)
    for spine_switch in spine_switches:
        spine_switch.set_hash_algorithm(consistent_hash_in_spine_switch)

    # 用户和管理员访问交换机
    admin.set_node(spine_switches[0])
    for user in users:
        user.set_node(spine_switches[0])

    # 用户开始写入和读取数据
    for user in users:
        user.write(write_number=data_length * (1 - same_data_ratio))

    # 管理员写入公共数据
    admin.generate_common_data(number=data_length * same_data_ratio)

    # 删除若干台服务器
    n1 = consistent_hash_in_leaf_switch.remove_node(servers[0])
    n2 = consistent_hash_in_leaf_switch.remove_node(servers[3])
    n3 = consistent_hash_in_leaf_switch.remove_node(servers[6])

    # 用户开始读取数据
    for user in users:
        user.read(read_number=data_length, same_data_ratio=same_data_ratio)

    # # 打印结果
    # print("hash: request_number:%d hit_number:%d hash hit accuracy:%.3f" %
    #       (consistent_hash_in_leaf_switch.request_number, consistent_hash_in_leaf_switch.hit_number,
    #        consistent_hash_in_leaf_switch.hit_accuracy()))
    #
    # for switch in consistent_hash_in_spine_switch.node_list:
    #     print("%s cache_size:%d" % (switch.name, len(switch.data)))
    #
    # for server in consistent_hash_in_leaf_switch.node_list:
    #     print("%s cache_size:%d data_shift_number:%d" % (server.name, len(server.data), server.data_shift_number))

    # 将结果写入到csv文件中，写入的内容包含预定义里面的参数
    data = {'user_number': user_number, 'data_length': data_length, 'request_number': request_number,
            'same_data_ratio': same_data_ratio, 'replica_number_in_spine_switch': replica_number_in_spine_switch,
            'replica_number_in_leaf_switch': replica_number_in_leaf_switch,'hit_number': consistent_hash_in_leaf_switch.hit_number,
            'hit_accuracy': consistent_hash_in_leaf_switch.hit_accuracy()}
    for switch in consistent_hash_in_spine_switch.node_list:
        data[switch.name + '_cache_size'] = len(switch.data)
    for server in consistent_hash_in_leaf_switch.node_list:
        data[server.name + '_cache_size'] = len(server.data)
        data[server.name + '_data_shift_number'] = server.data_shift_number
    df=pd.DataFrame(data,index=[0])
    # 判断consistent_hash_result.csv是否存在
    if not os.path.exists('common_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number)):
        df.to_csv('consistent_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number),mode='a',header=True,index=False)
    else:
        df.to_csv('consistent_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number),mode='a',header=False,index=False)

    # if not os.path.exists('common_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number)):
    #     df.to_csv('common_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number),mode='a',header=True,index=False)
    # else:
    #     df.to_csv('common_hash_result_leaf_switch%d_server%d.csv' % (leaf_switch_number,server_number),mode='a',header=False,index=False)